#-*- coding: utf-8
import cgi
from models import CoolCategory
from models import CoolTag
from models import CoolBookmark
from models import CoolComment
from urllib import unquote
from google.appengine.api import users
import os
import datetime
import PyRSS2Gen
import re
from google.appengine.ext import webapp
from google.appengine.ext.webapp import template
from google.appengine.ext.webapp.util import run_wsgi_app
import zlib
from gmemsess import Session
from service import Image
import Cookie

class PublicPage(webapp.RequestHandler):    
    
    def render(self, template_file, template_value):
        path = os.path.join(os.path.dirname(__file__), template_file)
        self.response.out.write(template.render(path, template_value))
    
    def error(self,code):
        if code==400:
            self.response.set_status(code)
        else:
            self.response.set_status(code)
            
    def is_admin(self):
        return users.is_current_user_admin()
    
    def head(self, *args):
        return self.get(*args) 
    
class MainPage(PublicPage):
    def get(self):
        
        user = users.get_current_user()
        #if user:
        #    categorys = CoolCategory.all().filter('owner = ', user)
        #    bookmarks = CoolBookmark.all().filter("owner = ", user)
        #else:
        #    categorys = CoolCategory.all()
        #    bookmarks = CoolBookmark.all().filter("privilege = ", "public")
        categorys = CoolCategory.all()
        bookmarks = CoolBookmark.all().filter("privilege = ", "public")

        tags = CoolTag.all().order('-bookmarkcount').fetch(30)

        page_size = 10
        max_page = (bookmarks.count() + page_size - 1) / page_size
        page = 1
        page_pattern = re.compile('/page/(\d+)$')
        pattern_list = page_pattern.findall(self.request.path)
        if pattern_list:
            page = int(pattern_list[0])
        if page > max_page:
            page = max_page
        if page <= 0:
            page = 1
        offset = (page - 1) * page_size

        show_prev = False
        show_next = False
        show_prev = not (page == 1)
        show_next = not (page == max_page)
        page_list = []
        cnt = 1
        while cnt < max_page:
            page_list.append(cnt)
            cnt += 1
        
        bookmarks = bookmarks.order('-createtime').fetch(page_size, offset = offset)
        pageurl = '/'
      
        template_value={"user": user,
                        "bookmarks": bookmarks,
                        "categorys": categorys,
                        "tags": tags,
                        'pageurl': pageurl,
                        'show_prev': show_prev,
                        'show_next': show_next,
                        'prev': page - 1,
                        'next': page + 1,
                        'page': page,
                        'max_page': max_page,
                        'page_list': page_list,
                        'login_url': users.CreateLoginURL(self.request.uri),
                        'logout_url': users.CreateLogoutURL(self.request.uri),
                        }
        self.render('template/index.html', template_value)

class Search(PublicPage):
    def post(self):
        name = unicode(self.request.get('s'))
        bookmarks = CoolBookmark.all().filter('name > ', name).filter('name < ', name + u"\ufffd")

        user = users.get_current_user()
        #if user:
        #    categorys = CoolCategory.all().filter('owner = ', user)
        #    bookmarks = CoolBookmark.all().filter("owner = ", user)
        #else:
        #    categorys = CoolCategory.all()
        #    bookmarks = CoolBookmark.all().filter("privilege = ", "public")
        categorys = CoolCategory.all()
        bookmarks = bookmarks.filter("privilege = ", "public")
            
        tags = CoolTag.all().order('-bookmarkcount').fetch(30)
      
        template_value={"user": user,
                        "bookmarks": bookmarks,
                        "categorys": categorys,
                        "tags": tags,
                        'login_url': users.CreateLoginURL(self.request.uri),
                        'logout_url': users.CreateLogoutURL(self.request.uri),
                        }
        self.render('template/index.html', template_value)

class Bookmark(PublicPage):
    def get(self,id):        
        bookmark=CoolBookmark.get_by_id(int(id))        
        
        if not bookmark:
            return self.error(404)
        
        accesscount = bookmark.accesscount + 1
        bookmark.accesscount = accesscount
        bookmark.put()
        
        comments = CoolComment.all().filter('bookmark = ', bookmark).order('-createtime')        

        user = users.get_current_user()
        #if bookmark.privilege == "private" and bookmark.owner != user:
        #    return self.error(404)
        #if user:
        #    categorys = CoolCategory.all().filter('owner = ', user)            
        #else:
        #    categorys = CoolCategory.all()
        categorys = CoolCategory.all()
        
        tags = CoolTag.all().order('-bookmarkcount').fetch(30)
        
        template_value={"user": user,
                        "bookmark": bookmark,
                        "comments": comments,
                        "categorys": categorys,
                        "tags": tags,
                        'login_url': users.CreateLoginURL(self.request.uri),
                        'logout_url': users.CreateLogoutURL(self.request.uri),
                        }
        self.render('template/viewbookmark.html', template_value)

class Category(PublicPage):
    def get(self,id):
        id=int(id)
        category=CoolCategory.get_by_id(int(id))
        
        if not category:
            return self.error(404)

        bookmarks = CoolBookmark.all().filter('category = ', category)
        user = users.get_current_user()
        #if user:
        #    categorys = CoolCategory.all().filter('owner = ', user)
        #    bookmarks = bookmarks.filter('owner = ', user)
        #else:
        #    categorys = CoolCategory.all()
        #    bookmarks = bookmarks.filter("privilege = ", "public")
        categorys = CoolCategory.all()
        bookmarks = bookmarks.filter("privilege = ", "public")

        tags = CoolTag.all().order('-bookmarkcount').fetch(30)

        page_size = 10
        max_page = (bookmarks.count() + page_size - 1) / page_size
        page = 1
        page_pattern = re.compile('/page/(\d+)$')
        pattern_list = page_pattern.findall(self.request.path)
        if pattern_list:
            page = int(pattern_list[0])
        if page > max_page:
            page = max_page
        if page <= 0:
            page = 1
        offset = (page - 1) * page_size

        show_prev = False
        show_next = False
        show_prev = not (page == 1)
        show_next = not (page == max_page)
        page_list = []
        cnt = 1
        while cnt < max_page:
            page_list.append(cnt)
            cnt += 1
        
        bookmarks = bookmarks.order('-createtime').fetch(page_size, offset = offset)
        pageurl = '/category/%s/' % id
      
        template_value={"user": user,
                        "bookmarks": bookmarks,
                        "categorys": categorys,
                        "tags": tags,
                        'pageurl': pageurl,
                        'show_prev': show_prev,
                        'show_next': show_next,
                        'prev': page - 1,
                        'next': page + 1,
                        'page': page,
                        'max_page': max_page,
                        'page_list': page_list,
                        'login_url': users.CreateLoginURL(self.request.uri),
                        'logout_url': users.CreateLogoutURL(self.request.uri),
                        }
        self.render('template/index.html', template_value)

class Tag(PublicPage):
    def get(self,id):
        id=int(id)
        tag=CoolTag.get_by_id(int(id))
        
        if not tag:
            return self.error(404)

        bookmarks = CoolBookmark.all().filter('tags = ', tag.name).order('-createtime')
        
        user = users.get_current_user()
        categorys = CoolCategory.all()
        bookmarks = bookmarks.filter('privilege = ', 'public')
            
        tags = CoolTag.all().order('-bookmarkcount').fetch(30)
        
        page_size = 10
        max_page = (bookmarks.count() + page_size - 1) / page_size
        page = 1
        page_pattern = re.compile('/page/(\d+)$')
        pattern_list = page_pattern.findall(self.request.path)
        if pattern_list:
            page = int(pattern_list[0])
        if page > max_page:
            page = max_page
        if page <= 0:
            page = 1
        offset = (page - 1) * page_size

        show_prev = False
        show_next = False
        show_prev = not (page == 1)
        show_next = not (page == max_page)
        page_list = []
        cnt = 1
        while cnt < max_page:
            page_list.append(cnt)
            cnt += 1
        
        bookmarks = bookmarks.order('-createtime').fetch(page_size, offset = offset)
        pageurl = '/tag/%s/' % id
      
        template_value={"user": user,
                        "bookmarks": bookmarks,
                        "categorys": categorys,
                        "tags": tags,
                        'pageurl': pageurl,
                        'show_prev': show_prev,
                        'show_next': show_next,
                        'prev': page - 1,
                        'next': page + 1,
                        'page': page,
                        'max_page': max_page,
                        'page_list': page_list,
                        'login_url': users.CreateLoginURL(self.request.uri),
                        'logout_url': users.CreateLogoutURL(self.request.uri),
                        }
        self.render('template/index.html', template_value)

class TagByName(PublicPage):
    def get(self):
        tag_pattern = re.compile('/tag/s/(\S+)$')
        tag_list = tag_pattern.findall(self.request.path)
        if tag_list:
            name = unquote(tag_list[0])
        name = str(name).decode("utf8")

        bookmark = CoolBookmark.all().filter("tags = ", name)

        
        user = users.get_current_user()
        categorys = CoolCategory.all()
        bookmarks = bookmark.filter("privilege = ", 'public')
            
        tags = CoolTag.all().order('-bookmarkcount').fetch(30)
        
        page_size = 10
        max_page = (bookmarks.count() + page_size - 1) / page_size
        page = 1
        page_pattern = re.compile('/page/(\d+)$')
        pattern_list = page_pattern.findall(self.request.path)
        if pattern_list:
            page = int(pattern_list[0])
        if page > max_page:
            page = max_page
        if page <= 0:
            page = 1
        offset = (page - 1) * page_size

        show_prev = False
        show_next = False
        show_prev = not (page == 1)
        show_next = not (page == max_page)
        page_list = []
        cnt = 1
        while cnt < max_page:
            page_list.append(cnt)
            cnt += 1
        
        bookmarks = bookmarks.order('-createtime').fetch(page_size, offset = offset)
        pageurl = '/tag/s/%s/' % name
      
        template_value={"user": user,
                        "bookmarks": bookmarks,
                        "categorys": categorys,
                        "tags": tags,
                        'pageurl': pageurl,
                        'show_prev': show_prev,
                        'show_next': show_next,
                        'prev': page - 1,
                        'next': page + 1,
                        'page': page,
                        'max_page': max_page,
                        'page_list': page_list,
                        'login_url': users.CreateLoginURL(self.request.uri),
                        'logout_url': users.CreateLogoutURL(self.request.uri),
                        }
        self.render('template/index.html', template_value)

class AddComment(PublicPage):
    def post(self):
        bookmark_id = int(self.request.get('id'))
        checkcode = self.request.get('checkcode')
        sess = Session(self, timeout=180)
        if str(checkcode) == str(sess['checkcode']): 
            content = cgi.escape(self.request.get('content'))
            if len(content) > 500:
                content = content[:500]
            bookmark = CoolBookmark.get_by_id(bookmark_id)
    
            comment = CoolComment()
            comment.owner = users.get_current_user()
            comment.content = content
            comment.bookmark = bookmark
            comment.put()
    
            commentcount = CoolComment.all().filter('bookmark = ', bookmark).count()
            bookmark.comments = commentcount
            bookmark.put()
        
        self.redirect('/bookmark/%s' % bookmark_id)

class ShowImage(webapp.RequestHandler):
    def get(self, id):
        bookmark = CoolBookmark.get_by_id(int(id))
        if bookmark:
            self.response.headers['Content-Type'] = "image"
            self.response.out.write(bookmark.image)
            
class ShowContent(webapp.RequestHandler):
    def get(self, id):
        bookmark = CoolBookmark.get_by_id(int(id))
        if bookmark:
            self.response.headers['Content-Type'] = "text/html"
            decomp = zlib.decompressobj()
            content = decomp.decompress(bookmark.zipcontent)
            self.response.out.write(content)

class Vote(webapp.RequestHandler):
    def post(self):
        bookmark_id = str(self.request.get('bookmarkid'))
        voted = self.request.cookies.get(bookmark_id)
        if voted:
                self.response.out.write("You have voted.")         
        else:
            cookie = Cookie.SimpleCookie()
            cookie[bookmark_id] = bookmark_id
            self.response.headers.add_header('Set-Cookie', cookie[bookmark_id].OutputString()) 
            
            bookmark = CoolBookmark.get_by_id(int(bookmark_id))
            thisvote = int(self.request.get('stars'))            
            if bookmark:
                total_vote_count = bookmark.totalvotecount + 1            
                total_vote = bookmark.totalvote + thisvote
                bookmark.totalvote = total_vote
                bookmark.totalvotecount = total_vote_count
                bookmark.put()            
            self.response.out.write(bookmark.starrate)
            

class RSS(webapp.RequestHandler):
    def get(self):
        bookmarks = CoolBookmark.all().filter("privilege = ", "public").order('-createtime').fetch(10)
        items = []
        for bookmark in bookmarks:
            item = PyRSS2Gen.RSSItem(
                    title = bookmark.name,
                    categories = bookmark.tags,
                    link = bookmark.url,
                    description = bookmark.description,
                    guid = PyRSS2Gen.Guid(bookmark.url),
                    pubDate = bookmark.createtime)
            items.append(item)
            
        rss = PyRSS2Gen.RSS2(
            title = "Cool Bookmark feed",
            link = "http://findlettoo.appspot.com",
            description = "This is a cool bookmark.",
            lastBuildDate = datetime.datetime.now(),
            items = items)

        self.response.headers['Content-Type'] = "text/xml"
        self.response.out.write(rss.to_xml())

class CheckCode(webapp.RequestHandler):
    def get(self):
        img = Image()
        imgdata = img.create()
        sess=Session(self,timeout=900)
        if not sess.is_new():
            sess.invalidate()
            sess=Session(self,timeout=900)
        sess['checkcode'] = img.text
        sess.save()
        
        self.response.headers['Content-Type'] = "image/png"
        self.response.out.write(imgdata)

def main():
  webapp.template.register_template_library('filter')
  application = webapp.WSGIApplication(
                                     [('/', MainPage),
                                      ('/page/\\d+', MainPage),
                                      (r'/bookmark/(?P<id>[0-9]+)', Bookmark),
                                      ('/category/(?P<id>[0-9]+)', Category),
                                      ('/category/(?P<id>[0-9]+)/page/\\d+', Category),                                      
                                      ('/tag/(?P<id>[0-9]+)', Tag),
                                      ('/tag/(?P<id>[0-9]+)/page/\\d+', Tag),
                                      ('/tag/s/\\S+', TagByName),
                                      ('/tag/s/\\S+/page/\\d+', TagByName),
                                      ('/bookmark/addcomment', AddComment),
                                      ('/bookmark/image/(?P<id>[0-9]+)', ShowImage),
                                      ('/bookmark/snapshot/(?P<id>[0-9]+)', ShowContent),
                                      ('/bookmark/vote', Vote),
                                      ('/search', Search),
                                      ('/checkcode', CheckCode),
                                      ('/rss', RSS)],
                                     debug=True)
  run_wsgi_app(application)

if __name__ == "__main__":
  main()
